/**
 * 
 */
package pacMan;

import java.util.HashMap;
import java.util.Map;

/**
 * Enumeration: CardinalDirection
 * 
 * Used to manage travel vectors for mobile objects derived from BasicDrawableObject.
 * 
 * @author 		Tomas Rivera
 * @version 	$Id$
 *
 */
public enum CardinalDirection {
	/*
	 * Directional values are based on standard keyboard keycodes for
	 * arrow buttons.
	 * 
	 *  North - 38
	 *  South - 40
	 *  East - 39
	 *  West - 37
	 *  
	 */
	NORTH(38), EAST(39), SOUTH(40), WEST(37), VNONE(2), HNONE(1), NONE(0);
	
	
	//////////////////////////////////////////////////////////
	// Constructor methods
	//////////////////////////////////////////////////////////
	
	/**
	 * This is used to track the direction an object is facing
	 * or attempting to travel in.
	 * 
	 * @param direction
	 */
	private CardinalDirection(int direction) {
		this.direction = direction;
	}
	
	//////////////////////////////////////////////////////////
	// Public methods
	//////////////////////////////////////////////////////////
	
	/**
	 * Get the String representation of the enum.
	 * 
	 * @return
	 */
	public String toString() {
		switch(direction) {
			case 38:
				return "NORTH";
			case 40:
				return "SOUTH";
			case 39:
				return "EAST";
			case 37:
				return "WEST";
			case 0:
				return "VNONE";
			case 1:
				return "HNONE";
			default:
				return "NONE";
		}
	}
	
	/**
	 * Get the numeric value of the enum.
	 * 
	 * @return
	 */
	public int getValue() {
		return direction;
	}
	
	/**
	 * Get a random direction.
	 * 
	 * @return
	 */
	public static CardinalDirection pickRandomDirection() {
		int value = (int)(4.0 * Math.random()) + 37;
		return valueOf(value);
	}
	
	/**
	 * Translate keycode to CardinalDirection enum.
	 * 
	 * @param dir
	 * @return
	 */
	public static CardinalDirection valueOf(int dir) {
		return map.get(dir);
	}
	
	/**
	 * Return the opposite of the current value of direction.
	 * 
	 * @return
	 */
	public CardinalDirection opposite() {
		switch(direction) {
			case 37:
				return CardinalDirection.EAST;
			case 38:
				return CardinalDirection.SOUTH;
			case 39:
				return CardinalDirection.WEST;
			case 40:
				return CardinalDirection.NORTH;
			default:
				assert false;
				break;
		}
		
		return null;
	}
	

	//////////////////////////////////////////////////////////
	// Private member variables
	//////////////////////////////////////////////////////////
	
	private int direction;
	private static Map<Integer, CardinalDirection> map = new HashMap<Integer, CardinalDirection>();
	
	static {
		for (CardinalDirection dir : CardinalDirection.values()) {
			map.put(dir.direction, dir);
		}
	}
}
